/**
 * @file    woshkiosk.cpp
 * @brief   Main (entry point) of WOSH Remote [woshkiosk].
 *
 * \see     wosh::application::WoshKioskWindow
 ****************************************************************************
 * \section page_applications_woshkiosk WOSH KiosK [Multiplatform]
 *
 * \warning WOSH KiosK is under planning.
 *
 *
 * Here are some screenshots:
 * \image html extras/screenshots/WOSH.KiosK.Preview1.png "WOSH KiosK Preview 1"
 * \image html extras/screenshots/WOSH.KiosK.Preview2.png "WOSH KiosK Preview 2"
 * \image html extras/screenshots/WOSH.KiosK.Preview3.png "WOSH KiosK Preview 3"
 *
 *
 ****************************************************************************
 * @version $Id: woshkiosk.cpp 2618 2010-06-04 09:48:15Z alex $
 * @author  Alessandro Polo
 ****************************************************************************/
/* Copyright (c) 2007-2010, WOSH - Wide Open Smart Home 
 * by Alessandro Polo - OpenSmartHome.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the OpenSmartHome.com WOSH nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ******************************************************************************/

//////////////////////////////////////////////////////////////////
#define _CONFIG_FILE		"../etc/wosh/wosh.kiosk.conf"
#define _LOG_FILE			"../var/log/wosh.kiosk.log"
//////////////////////////////////////////////////////////////////

#include <core/WoshKernel.h>
#include <core/ObjectFactory.h>
#include <core/BundleManager.h>
#include <core/BusManager.h>
#include <core/LogHandlers.h>

#include <bundles/services/DiscoveryUdp/DiscoveryUdpBundle.h>

#include <framework/gui/BusRingQt.h>
#include <framework/gui/GuiUtilities.h>

#include <framework/gui/kiosk/KioskManager.h>
#include <framework/gui/kiosk/LayoutStandard.h>

   #include <framework/gui/modules/FormNetworkManager.h>
   #include <framework/gui/bundles/services/GadgetCommunicationBox.h>
   #include <framework/gui/bundles/devices/GadgetModem.h>
   #include <framework/gui/kiosk/GadgetStatus.h>
   #include <framework/gui/kiosk/SheetAdmin.h>
   #include <framework/gui/kiosk/SheetHome.h>

//////////////////////////////////////////////////////////////////
#include "WoshKioskWindow.h"
#include <QApplication>
#include <QtGui>


using namespace std;
using namespace wosh;
using namespace wosh::gui;
using namespace wosh::application;

int main(int argc, char **argv)
 {
	//////////////////////////////////////////////////////////////////////////////////////
	// init QT and its resources
	Q_INIT_RESOURCE(woshkiosk);
	QApplication app(argc, argv);

	//////////////////////////////////////////////////////////////////////////////////////
	// splash screen
	QSplashScreen splash( QPixmap(":/wosh.splash.icarus.png") );
	splash.setFont( QFont("Tahoma", 12, 1, false) );
	splash.showMessage("Initializing..", Qt::AlignBottom, QColor(Qt::white));
	splash.show();
	app.processEvents();

	//////////////////////////////////////////////////////////////////////////////////////
	// setup defauld Log-handler
	DefaultSharedLogHandler::getInstance()->setFileName( _LOG_FILE );
	DefaultSharedLogHandler::getInstance()->setStdOut(false);

	//////////////////////////////////////////////////////////////////////////////////////
	splash.showMessage("Loading Settings..", Qt::AlignBottom, QColor(Qt::white)); app.processEvents();
	//////////////////////////////////////////////////////////////////////////////////////
	// load settings for command line arguments, default configuration file and folders
	// WOSH configuration architecture is similar to Apache2
	Settings* woshSettings = new Settings();
	woshSettings->loadFromArgs(argc, argv);

	std::string cfgFile = woshSettings->getValueOf( "", "ConfigFile", _CONFIG_FILE ).toString();
	WRESULT loaded = woshSettings->loadConfigurationFile( cfgFile );
	while ( loaded != WRET_OK ) {
		GuiUtilities::aboutError_woshconf( NULL, cfgFile );
		QString fileName = QFileDialog::getOpenFileName(NULL, "Open WOSH configuration file", "../etc/wosh", "Configuration file (*.conf);;All files (*.*)" );
		if ( fileName.isNull() )
			return 1;
		cfgFile.assign( fileName.toLatin1().data() );
		loaded = woshSettings->loadConfigurationFile( cfgFile );
	 }
	std::string woshName = woshSettings->getValueOf( "WoshKernel", "Name", "" ).toString();

	//////////////////////////////////////////////////////////////////////////////////////
	splash.showMessage( QString("Allocating WoshKernel [%1]..").arg(woshName.c_str()), Qt::AlignBottom, QColor(Qt::white)); app.processEvents();
	//////////////////////////////////////////////////////////////////////////////////////
	// alloc Kernel
	WoshKernel core( woshName, woshSettings );

	//////////////////////////////////////////////////////////////////////////////////////
	splash.showMessage( QString("Initializing Kernel [%1]..").arg(woshName.c_str()), Qt::AlignBottom, QColor(Qt::white)); app.processEvents();
	//////////////////////////////////////////////////////////////////////////////////////
	// now we installed and configured all CORE modules, we can init kernel (them)
	// (so bundles will be loaded, if autoload is set)
	core.init();

	//////////////////////////////////////////////////////////////////////////////////////
	// install some required blundles (and apply their settings)
	//////////////////////////////////////////////////////////////////////////////////////
	splash.showMessage( "Installing Discovery Bundle..", Qt::AlignBottom, QColor(Qt::white)); app.processEvents();
	Bundle* discoveryBundle = ObjectFactory::createTypeOf<Bundle>("wosh::services::DiscoveryUdpBundle", 0.0);
	core.bundles().installBundle( discoveryBundle );

	//////////////////////////////////////////////////////////////////////////////////////
	splash.showMessage( "Initializing GUI Bus..", Qt::AlignBottom, QColor(Qt::white)); app.processEvents();
	//////////////////////////////////////////////////////////////////////////////////////
	// install custom BUS for the GUI (required cos of multi-threading vs. message passing)
	core.busses().registerBus( new BusRingQt(_Bus_Gui) );

	//////////////////////////////////////////////////////////////////////////////////////
	splash.showMessage( QString("Starting Kernel [%1]..").arg(woshName.c_str()), Qt::AlignBottom, QColor(Qt::white)); app.processEvents();
	//////////////////////////////////////////////////////////////////////////////////////
	// enter loop (acquire thread), it will set kernel-state to running
	// (so bundles will start, if autostart is set)
	core.start();

	//////////////////////////////////////////////////////////////////////////////////////
	splash.showMessage( "Initializing GUI..", Qt::AlignBottom, QColor(Qt::white)); app.processEvents();
	//////////////////////////////////////////////////////////////////////////////////////
	// setup kiosk manager
	KioskManager* kManager = new KioskManager();
	LayoutStandard kLayout;
	kManager->setLayout(&kLayout);

	KioskSheetProxy* kp1 = new KioskSheetProxy(new QLabel("HELLO SHEET1")); kp1->setName("sheet1");
	kManager->registerSheet( kp1 );
	KioskSheetProxy* kp2 = new KioskSheetProxy(new QLabel("HELLO SHEET2")); kp2->setName("sheet2");
	kManager->registerSheet( kp2 );
	KioskSheetProxy* kp4 = new KioskSheetProxy(new FormNetworkManager(), 0); kp4->setName("KiosK::Sheet::Network");
	kManager->registerSheet( kp4 );
	GadgetModem* gtmp = new GadgetModem();
	kManager->registerGadget( gtmp );

	kManager->registerGadget( new GadgetStatus() );
	kManager->registerGadget( new GadgetCommunicationBox() );
//	kLayout.setSheet( new KioskSheetProxy(new QLabel("HELLO SHEET")) );
//	kLayout.addGadget( new KioskGadgetProxy(new QTabWidget()) );
//	kLayout.addGadget( gtmp );
//	kLayout.addGadget( new KioskGadgetProxy(new QPushButton()) );

	kManager->getLayout()->setSheet( kp1->asQGraphicsWidget() );

	kManager->registerSheet( new SheetAdmin() );
	kManager->registerSheet( new SheetHome() );

	kManager->init();
	kManager->refreshView();
	//////////////////////////////////////////////////////////////////////////////////////
	// setup main window
	WoshKioskWindow* window = new WoshKioskWindow();
	splash.finish(window);
	window->setManager(kManager);
	window->setScene( kLayout.getScene() );
	window->init();
	window->show();
	//////////////////////////////////////////////////////////////////////////////////////
	// enter application loop
	core.start();
	int app_ret = app.exec();
	core.shutdown();

	//////////////////////////////////////////////////////////////////////////////////////
	// stop Bundles explicitly (not needed since it will be done by bundlefactory/kernel)
	core.bundles().stopBundles(); 

	//////////////////////////////////////////////////////////////////////////////////////
	delete window; window = NULL;
	delete kManager; kManager = NULL;
	//////////////////////////////////////////////////////////////////////////////////////
	return app_ret;
 }
